﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using System.ComponentModel;
using DevExpress.XtraEditors.Controls;
using System.Windows.Forms;
using DevExpress.XtraEditors.Registrator;
using System.IO;

namespace ProgNetComponentsDx.Controls.Editors
{
    public class FileDialogEdit : ButtonEdit
    {
        [Browsable(false)]
        public override string EditorTypeName { get { return "FileDialogEdit"; } }

        protected override void CreateRepositoryItem()
        {
            fProperties = new RepositoryItemFileDialog();
            (this.fProperties as RepositoryItemFileDialog).SetOwner(this);
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public new RepositoryItemFileDialog Properties
        {
            get { return fProperties as RepositoryItemFileDialog; }
        }
    }

    [UserRepositoryItem("Register")]
    public class RepositoryItemFileDialog : RepositoryItemButtonEdit, ICustomTypeDescriptor
    {
        #region static
        static RepositoryItemFileDialog()
        {
            Register();
        }
        public static void Register()
        {
            EditorRegistrationInfo.Default.Editors.Add(
                new EditorClassInfo("FileDialogEdit",
                                typeof(FileDialogEdit),
                                typeof(RepositoryItemFileDialog),
                                typeof(DevExpress.XtraEditors.ViewInfo.LookUpEditViewInfo),
                                new DevExpress.XtraEditors.Drawing.ButtonEditPainter(),
                                true,
                                null));
        }
        #endregion

        #region override
        [Browsable(false)]
        public override string EditorTypeName { get { return "FileDialogEdit"; } }
        public override BaseEdit CreateEditor()
        {
            return new FileDialogEdit();
        }
        public override void Assign(RepositoryItem item)
        {
            base.Assign(item);
            RepositoryItemFileDialog dlg = item as RepositoryItemFileDialog;
            if (dlg != null)
            {
                this.FileOperation = dlg.FileOperation;
                this.UseRootAsPath = dlg.UseRootAsPath;
                this.RootName = dlg.RootName;
                this.RootDir = dlg.RootDir;
                AssingProperties(FileDialog, dlg.FileDialog);
            }
        }
        public override void CreateDefaultButton()
        {
            _OpenButton = new EditorButton("EDIT", ButtonPredefines.Ellipsis);
            _ClearButton = new EditorButton("DELETE", ButtonPredefines.Delete);
            this.Buttons.Add(_ClearButton);
            this.Buttons.Add(_OpenButton);
        }

        #endregion

        #region private methods
        internal void SetOwner(FileDialogEdit edit)
        {
            base.SetOwnerEdit(edit);
        }
        private void RepositoryItemFileDialog_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            BaseEdit ed = sender as BaseEdit;
            if (ed != null)
            {
                if (e.Button.Tag.AsString() == "DELETE" && !ReadOnly)
                    ed.EditValue = null;
                else if (e.Button.Tag.AsString() == "EDIT" && !ReadOnly)
                {
                    if (ed.EditValue.IsNotNull())
                    {
                        if (ed.EditValue is string)
                        {
                            try
                            {
                                string path = ed.EditValue.AsString();
                                if (RootDir.IsNotNull() && UseRootAsPath)
                                    path = path.XReplace("^%" + RootName + "%", RootDir);

                                FileDialog.FileName = path;
                                FileDialog.InitialDirectory = Path.GetDirectoryName(path);
                            }
                            catch { }
                        }
                        else if (ed.EditValue is string[])
                        {
                            string[] s = (ed.EditValue as string[]);
                            if(s.Length>0)
                            try
                            {
                                FileDialog.InitialDirectory = Path.GetDirectoryName(s[0]);
                            }
                            catch { }
                        }
                    }
                    if (FileDialog.ShowDialog() == DialogResult.OK)
                    {
                        if (FileDialog.FileNames != null && FileDialog.FileNames.Length > 1)
                            ed.EditValue = FileDialog.FileNames;
                        else
                        {
                            string path = FileDialog.FileName.AsString();
                            if (RootDir.IsNotNull() && UseRootAsPath)
                                path = path.XReplace("^" + RootDir.XEscape(), "%" + RootName + "%");
                            ed.EditValue = path;
                        }
                    }
                }
            }
        }
        private void AssingProperties(FileDialog d1, FileDialog d2)
        {
            d1.AddExtension = d2.AddExtension;
            d1.AutoUpgradeEnabled = d2.AutoUpgradeEnabled;
            d1.CheckFileExists = d2.CheckFileExists;
            d1.CheckPathExists = d2.CheckPathExists;
            d1.DefaultExt = d2.DefaultExt;
            d1.DereferenceLinks = d2.DereferenceLinks;
            d1.FileName = d2.FileName;
            d1.Filter = d2.Filter;
            d1.FilterIndex = d2.FilterIndex;
            d1.InitialDirectory = d2.InitialDirectory;
            d1.RestoreDirectory = d2.RestoreDirectory;
            d1.ShowHelp = d2.ShowHelp;
            d1.SupportMultiDottedExtensions = d2.SupportMultiDottedExtensions;
            d1.Tag = d2.Tag;
            d1.Title = d2.Title;
            d1.ValidateNames = d2.ValidateNames;
        }
        #endregion

        #region CTOR
        public RepositoryItemFileDialog()
            : base()
        {
            ButtonClick += new ButtonPressedEventHandler(RepositoryItemFileDialog_ButtonClick);
        }
        #endregion

        #region members
        private SaveFileDialog _sdlg = new SaveFileDialog();
        private OpenFileDialog _odlg = new OpenFileDialog();
        private FileOperation _FileOperation = FileOperation.Open;
        private EditorButton _OpenButton;
        private EditorButton _ClearButton;
        #endregion

        #region Properties
        [Category(ProgNetComponents.Constants.Categories.FolderDialog)]
        public bool UseRootAsPath { get; set; }

        [DefaultValue("")]
        [Category(ProgNetComponents.Constants.Categories.FolderDialog)]
        public string RootDir
        {
            get;
            set;
        }

        [DefaultValue(null)]
        [Category(ProgNetComponents.Constants.Categories.FolderDialog)]
        public string RootName
        {
            get;
            set;
        }

        [RefreshProperties(RefreshProperties.All)]
        public FileOperation FileOperation
        {
            get { return _FileOperation; }
            set
            {
                if (_FileOperation != value)
                {
                    _FileOperation = value;
                    if (value == FileOperation.Save)
                        AssingProperties(_odlg, _sdlg);
                    else
                        AssingProperties(_sdlg, _odlg);
                }
            }
        }

        protected FileDialog FileDialog
        {
            get
            {
                if (FileOperation == FileOperation.Open)
                    return _odlg;
                else
                    return _sdlg;
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [ProgNetComponents.Design.Attributes.BrowsableByPropertyValue("FileOperation", FileOperation.Save)]
        public SaveFileDialog SaveFileDialog
        {
            get { return _sdlg; }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
         [ProgNetComponents.Design.Attributes.BrowsableByPropertyValue("FileOperation", FileOperation.Open)]
        public OpenFileDialog OpenFileDialog
        {
            get { return _odlg; }
        }
        #endregion

        #region ICustomTypeDescriptor Members

        public virtual AttributeCollection GetAttributes()
        {

            return TypeDescriptor.GetAttributes(this, true);
        }

        public virtual string GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }

        public virtual string GetComponentName()
        {

            return TypeDescriptor.GetComponentName(this, true);
        }

        public virtual TypeConverter GetConverter()
        {

            return TypeDescriptor.GetConverter(this, true);

        }

        public virtual EventDescriptor GetDefaultEvent()
        {

            return TypeDescriptor.GetDefaultEvent(this, true);
        }

        public virtual PropertyDescriptor GetDefaultProperty()
        {

            return TypeDescriptor.GetDefaultProperty(this, true);
        }

        public virtual object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }

        public virtual EventDescriptorCollection GetEvents(Attribute[] attributes)
        {

            return TypeDescriptor.GetEvents(this, attributes, true);
        }

        public virtual EventDescriptorCollection GetEvents()
        {

            return TypeDescriptor.GetEvents(this, true);
        }

        public virtual PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return GetProperties();
        }

        public virtual PropertyDescriptorCollection GetProperties()
        {
            return ProgNetComponents.Design.Attributes.DynamicPropertyAttribute.GetProperties(this);
        }

        public virtual object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }

        #endregion
    }

    public enum FileOperation
    {
        Open,
        Save
    }
}
